﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Mindfor.Web.Data;
using Mindfor.Web.Models;

namespace Mindfor.Web
{
	/// <summary>
	/// Provides extension function for ViewDataDictionary.
	/// </summary>
	public static class ViewDataExtensions
	{
		/// <summary>
		/// Returns eval value of <typeparam name="T"/> type from ViewData or Model by expression.
		/// If not found or can not be cast than returns defaulValue of <typeparam name="T"/>.
		/// </summary>
		/// <param name="viewData">ViewData.</param>
		/// <param name="expression">Expression to search.</param>
		/// <param name="defaultValue">DefaultValue to return if value is not found or can not be cast.</param>
		public static T Eval<T>(this ViewDataDictionary viewData, string expression, T defaultValue = default(T))
		{
			object o = viewData.Eval(expression);
			return o.To<T>(defaultValue);
		}

		/// <summary>
		/// Returns eval value of boolean type from ViewData or Model by expression.
		/// If not found or can not be cast than returns null.
		/// </summary>
		/// <param name="viewData">ViewData.</param>
		/// <param name="expression">Expression to search.</param>
		[Obsolete("Saved for compatibility. Recomend to use Eval<T> method.")]
		public static bool? EvalBool(this ViewDataDictionary viewData, string expression)
		{
			return Eval<bool?>(viewData, expression);
		}

		/// <summary>
		/// Gets page title data.
		/// </summary>
		/// <param name="viewData">ViewData to get page title from.</param>
		/// <returns>Page title.</returns>
		public static PageTitleCollection GetPageTitle(this ViewDataDictionary viewData)
		{
			return viewData["Page.Title"] as PageTitleCollection;
		}

		/// <summary>
		/// Sets page title data.
		/// </summary>
		/// <param name="viewData">ViewData to set page title to.</param>
		/// <param name="title">Page title data.</param>
		public static void SetPageTitle(this ViewDataDictionary viewData, PageTitleCollection title)
		{
			viewData["Page.Title"]  = title;
		}

		/// <summary>
		/// Gets page keywords.
		/// </summary>
		/// <param name="viewData">ViewData to get page keywords from.</param>
		/// <returns>Page keywords.</returns>
		public static string GetPageKeywords(this ViewDataDictionary viewData)
		{
			return viewData["Page.Keywords"] as string;
		}

		/// <summary>
		/// Sets page keywords.
		/// </summary>
		/// <param name="viewData">ViewData to set page keywords to.</param>
		/// <param name="keywords">Page keywords.</param>
		public static void SetPageKeywords(this ViewDataDictionary viewData, string keywords)
		{
			viewData["Page.Keywords"] = keywords;
		}

		/// <summary>
		/// Gets page description.
		/// </summary>
		/// <param name="viewData">ViewData to get page description from.</param>
		/// <returns>Page description.</returns>
		public static string GetPageDescription(this ViewDataDictionary viewData)
		{
			return viewData["Page.Description"] as string;
		}

		/// <summary>
		/// Sets page description.
		/// </summary>
		/// <param name="viewData">ViewData to set page description to.</param>
		/// <param name="description">Page description.</param>
		public static void SetPageDescription(this ViewDataDictionary viewData, string description)
		{
			viewData["Page.Description"] = description;
		}

		/// <summary>
		/// Returns value from value provider by key.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="valueProvider">Vallue provider.</param>
		/// <param name="key">Key to search.</param>
		/// <param name="defaultValue">Value to return if key not found or convertion failed.</param>
		/// <returns>Value from value provider.</returns>
		public static T GetValue<T>(this IValueProvider valueProvider, string key, T defaultValue = default(T))
		{
			ValueProviderResult result = valueProvider.GetValue(key);
			if (result == null)
				return defaultValue;

			try
			{
				return (T)result.ConvertTo(typeof(T));
			}
			catch
			{
				return defaultValue;
			}
		}
	}
}
